/*
 * Copyright (c) 2020 Fraunhofer FOKUS and others. All rights reserved.
 *
 * See the NOTICE file(s) distributed with this work for additional
 * information regarding copyright ownership.
 *
 * This program and the accompanying materials are made available under the
 * terms of the Eclipse Public License 2.0 which is available at
 * http://www.eclipse.org/legal/epl-2.0
 *
 * SPDX-License-Identifier: EPL-2.0
 *
 * Contact: mosaic@fokus.fraunhofer.de
 */
package org.eclipse.mosaic.fed.mapping.ambassador.spawning;

import org.apache.commons.lang3.builder.ToStringBuilder;
import org.apache.commons.lang3.builder.ToStringStyle;
import org.eclipse.mosaic.fed.mapping.ambassador.SpawningFramework;
import org.eclipse.mosaic.fed.mapping.config.units.CMultiAccessEdgeComputing;
import org.eclipse.mosaic.interactions.mapping.MecRegistration;
import org.eclipse.mosaic.lib.geo.GeoPoint;
import org.eclipse.mosaic.lib.util.NameGenerator;
import org.eclipse.mosaic.rti.api.IllegalValueException;
import org.eclipse.mosaic.rti.api.InternalFederateException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * Class responsible for configuring Multi-Access Edge Computing tobe added to the simulation
 */
public class MultiAccessEdgeComputingSpawner extends ServerSpawner {

    private static final Logger LOG = LoggerFactory.getLogger(MultiAccessEdgeComputingSpawner.class);

    private final String extName;

    private final GeoPoint position;

    private final double radius;

    private final double heading;

    private final double angle;

    private final boolean enableShow;

    /**
     * Constructor for {@link MultiAccessEdgeComputingSpawner}
     * Calls super constructor and sets additional parameters inferred from
     *json configuration
     *
     * @param multiAccessEdgeComputingConfiguration {@link CMultiAccessEdgeComputing} created from json configuration
     */
    public MultiAccessEdgeComputingSpawner(CMultiAccessEdgeComputing multiAccessEdgeComputingConfiguration) {
        super(
                multiAccessEdgeComputingConfiguration.applications,
                multiAccessEdgeComputingConfiguration.name,
                multiAccessEdgeComputingConfiguration.group
        );
        this.extName = multiAccessEdgeComputingConfiguration.name;
        this.position = multiAccessEdgeComputingConfiguration.position;
        this.radius = multiAccessEdgeComputingConfiguration.radius;
        this.heading = multiAccessEdgeComputingConfiguration.heading;
        this.angle = multiAccessEdgeComputingConfiguration.angle;
        this.enableShow = multiAccessEdgeComputingConfiguration.enableShow;
    }

    /**
     * Called by the {@link SpawningFramework} used to initialize the
     * Traffic Management Centers for the simulation
     *
     * @param spawningFramework the framework handling the spawning
     * @throws InternalFederateException if {@link MecRegistration} couldn't be handled by rti
     */
    public void init(SpawningFramework spawningFramework) throws InternalFederateException {
        String name = NameGenerator.getMecName();
        MecRegistration interaction = new MecRegistration(0, name, group, getAppList(), extName, position, radius, heading, angle, enableShow);
        try {
            LOG.info("Creating MEC: {}", this);
            spawningFramework.getRti().triggerInteraction(interaction);
        } catch (IllegalValueException e) {
            LOG.error("Exception while sending Interaction in TrafficManagementCenterSpawner.init()");
            throw new InternalFederateException("Exception while sending Interaction in TrafficManagementCenterSpawner.init()", e);
        }
    }


    @Override
    public String toString() {
        return new ToStringBuilder(this, ToStringStyle.SHORT_PREFIX_STYLE)
                .appendSuper(super.toString())
                .append("position", position)
                .append("radius", radius)
                .append("heading", heading)
                .append("angle", angle)
                .build();
    }
}
